using Pinwheel.Kernel;
using Pinwheel.Service.Protocol;

namespace Pinwheel.Service
{
    public partial class GatewayBase : ServiceBase
    {
        protected PID m_Watchdog;
        protected ServerSocket m_ServerSocket;

        public override void Create(IServiceManager serviceManager, IMessageQueue<ServiceMessage> messageQueue)
        {
            base.Create(serviceManager, messageQueue);
            // m_ServerSocket = new ServerSocket(this);
            m_Watchdog = serviceManager.GetServicePID("Watchdog");
            Assert.Check(m_Watchdog != PID.Invalid, $"[{Alias}]Create watchdog service not found");
        }

        public override int Init()
        {
            int code = base.Init();
            
            RegisterApi("Start", Start);
            RegisterApi("Forward", Forward);
            RegisterApi("Stop", Stop);

            #region Debug
            RegisterApi("Test", async message =>
            {
                if (message.Message is Test test)
                {
                    return new Test() {Value = test.Value + 1};
                }
                return null!;
            });
            #endregion
            
            return code;
        }

        private async ValueTask<IMessage> Forward(ServiceMessage message)
        {
            if (message.Message is Forward forward)
            {
                if (forward.Client != PID.Invalid && forward.Agent != PID.Invalid)
                {
                    if (Global.ClientConnectionMap.TryGetValue(forward.Client, out var connection))
                    {
                        connection.SetAgent(forward.Agent);
                        Global.ClientConnectionMap[forward.Client] = connection;
                    }
                }
            }

            return null!;
        }

        private async ValueTask<IMessage> Start(ServiceMessage message)
        {
            if (message.Message is Start start)
            {
                Assert.Check(m_ServerSocket == null!, $"[{Node}][{Alias}]Start server socket already exists");
                var port = start.Value1;
                var count = start.Value2 == 0 ? start.Value2 : ServerSocket.DefaultCount;
                m_ServerSocket = new ServerSocket(this, count, ServerSocket.DefaultBufferSize);
                m_ServerSocket.Listen(port);
            }
            return null!;
        }
        
        private async ValueTask<IMessage> Stop(ServiceMessage message)
        {
            if (message.Message is Stop)
            {
                m_ServerSocket.Close();
            }
            return null!;
        }
    }
}